package za.org.meraka.mu;

import java.io.*;

import java.util.regex.Pattern;
import java.util.regex.Matcher;

public class MxitUtilities {

//
// these words do not get changed
//
public static String[] special_words={
	"that",
	"thats",
	"cant",
	"dont",
	"wont"
};

//
// these consonant combinations can
// not bhe changed
//
public static String[] consonant_pairs={
	"bl", "br", 
	"ch", "cl", "cr", 
	"dr", 
	"fl", "fr",
	"gh", "gl", "gr",
	"ht",
	"kl",
	"ph", "pl", "pr",
	"sc", "sh", "sk", "sl", "sm", "sn", "sp", "sr", "st", "sw",
	"th", "tr", 
	"wh"};

//
// these are 'sound alikes'
//
public static String[][] sounds_like = {
	{ "ce", "se" },
	{ "ci", "si" },
	{ "cl", "kl" },
	{ "ct", "kt" },
	{ "ck", "k" },
	{ "pt", "p" },
	{ "ing", "in" },
	{ "mp", "m" },
	{ "ight", "yt" },
	{ "eight", "yt" },
	{ "aight", "yt" },
	{ "qu", "qw" },
	{ "qu", "kw" },
	{ "ph", "f" },
	{ "x", "sx" },
	{ "x", "xs" }
};

	static boolean clean = true;



//
// return true if stopword is NOT a mathword
// should all be in lowercase by this time
//
public static boolean compare(String original_stopword, String original_math_term, String original, String change) {


	String mathword = null;
	String stopword = original_stopword;

	if ( original_math_term.trim().equals("") )
		return true;

	if ( !original.equals("") ) {
		mathword = original_math_term.replace(original, change);
	}
	else {
		mathword = original_math_term;
	}

	int i;
	for(i=0; i< special_words.length; i++) {
		if ( special_words[i].equals(original_stopword) )
			return true;
	}

	//
	// change all to singular
	//
	//System.err.print("stemming stopword " + stopword);

	String singular_stopword = MxitUtilities.stem(stopword);
	//System.err.println(" singular_stopword " + singular_stopword);
	//System.err.print("stemming mathword " + mathword);

	String singular_mathword = MxitUtilities.stem(mathword);
	//System.err.println(" singular_mathword " + singular_mathword);
	//System.err.println("potential stopword " + stopword + " mathword " + mathword);

	stopword = singular_stopword;
	mathword = singular_mathword;


	//
	// equal
	//
	if ( stopword.equals(mathword) ) {
		return false;
	}

	//
	// if stopword and mathword are less than = 3 chars they must be
	// a direct match other wise keep it
	//
	/*
	if ( mathword.length() <= 3 ) {
		if ( mathword.equals(stopword) ) 
			return false;
		else
			return true;
	}
	*/

	/*
	if ( stopword.length() <= 3) {
		return true;
	}
	*/

	int sounds_like_index = -1;

	do {


		//System.err.println("sounds_like_index = " + sounds_like_index);
		if ( sounds_like_index != -1 ) {
			String pairs[] = sounds_like[sounds_like_index];
			//System.err.println("pairs[0] = " + pairs[0]);
			//System.err.println("pairs[1] = " + pairs[1]);
			if ( singular_mathword.indexOf(pairs[0]) != -1 ) {
				mathword = singular_mathword.replaceAll(pairs[0], pairs[1]);
				//System.err.println("sounds like mathword is now " + mathword);
			}
			else {
				sounds_like_index++;
				continue;
			}
		}

		//
		// remove the vowels from the word
		// y is considered a consonant if it starts a word but otherwise
   		// is a vowel.  So in year, yeah, yes it is a consonant but in
		// cycle geometry it is a vowel
		//
		String stopword_no_vowels = null;
		if ( stopword.startsWith("y") ) {
			stopword_no_vowels = stopword.replaceAll("[aeiou]", "");
		}
		else {
			stopword_no_vowels = stopword.replaceAll("[aeiou]y", "").replaceAll("[aeiou]", "");
		}

		//System.out.println("stopword no vowels is " + stopword_no_vowels);
	
		String mathword_no_vowels = null;
		if ( mathword.startsWith("y") ) {
			mathword_no_vowels = mathword.replaceAll("[aeiou]", "");
		}
		else {
			mathword_no_vowels = mathword.replaceAll("[aeiou]y", "").replaceAll("[aeiou]", "");;
		}

		//System.out.println("mathword no vowels is " + mathword_no_vowels);

		//
		// if they started with a vowel, however, put that
		// vowel back
		//
		String vowels[] = { "a", "e", "i", "o", "u" };
		for(i=0; i<vowels.length; i++ ) {
			if ( stopword.startsWith(vowels[i]) )  {
				stopword_no_vowels = new String(vowels[i] + stopword_no_vowels);
				//System.out.println(" adding " + vowels[i] + " to stopword so its " +
					//stopword_no_vowels);
			}
			if ( mathword.startsWith(vowels[i]) ) {
				mathword_no_vowels = new String(vowels[i] + mathword_no_vowels);
				//System.out.println(" adding " + vowels[i] + " to mathword so its " +
					//mathword_no_vowels);
			}
		}
	
		//System.err.println("stopword no vowels " + stopword_no_vowels);
		//System.err.println("mathword no vowels " + mathword_no_vowels);
	
	
		//
		// determine which consonants are NOT in the word
		//
		String mathword_excluded_consonants = new String("bcdfghjklmnpqrstvwxyz").replaceAll(
				"[" + mathword_no_vowels +"]", "");
		//System.err.println("mathword excluded consonents " + mathword_excluded_consonants);
	
		String mathword_no_vowels_wildcards = new String();
		if ( mathword_no_vowels.length() > 0 ) {
			if ( mathword.charAt(0) == mathword_no_vowels.charAt(0) )
				mathword_no_vowels_wildcards = new String("^");
		}
	
		for(i=0; i<mathword_no_vowels.length();i++) {
			mathword_no_vowels_wildcards = mathword_no_vowels_wildcards.concat("" +
				mathword_no_vowels.charAt(i) + ".*[~" + mathword_excluded_consonants +
					"].*");
		}
	
		//System.err.println("mathword no vowels wildcards " + mathword_no_vowels_wildcards);
	
		String stopword_no_vowels_wildcards = new String();
		if ( stopword_no_vowels.length() > 0 ) {
			if ( stopword.charAt(0) == stopword_no_vowels.charAt(0) )
				stopword_no_vowels_wildcards = new String("^");
		}
	
		for(i=0; i<stopword_no_vowels.length();i++) {
			stopword_no_vowels_wildcards = stopword_no_vowels_wildcards.concat("" +
				stopword_no_vowels.charAt(i) + ".*");
		}
	
		//System.err.println("stopword no vowels wildcards " + stopword_no_vowels_wildcards);
	
	
		//
		// this test is for all consonants in the right order and some special paris
		// must be together
		//
		if ( stopword_no_vowels.length() > 2 && stopword_no_vowels.equals(mathword_no_vowels) ) {
			//System.err.println("consonants equals " + stopword + " sounds_like_index is " +
			//		sounds_like_index);
			

			if ( sounds_like_index == -1 ) {
				//System.err.println("testing special pairs");
				//
				// there are some consonant combinations which are special
				// and won't have vowels between them like
				//
				boolean special_pair = false;
				for(i=0; i< consonant_pairs.length; i++) {
					//System.err.println("testing " + consonant_pairs[i]);
					//
					// has one of the special pairs
					//
					if ( mathword.indexOf(consonant_pairs[i]) != -1 ) {
						//System.err.println("mathword " + mathword + " has " +
						//	consonant_pairs[i]);
						special_pair = true;
						if ( stopword.indexOf(consonant_pairs[i]) != -1 ) {
							//System.err.println("special consonant pairs " + mathword + " " + stopword);
							return false;
						}
					}
				}
				if ( !special_pair )
					return false;
			}
			else
				return false;
		}
	
	
		//
		// consonants are the same but the order is mixed up
		//
		/*
		if ( stopword_no_vowels.replaceAll("[" + mathword_no_vowels + "]", "").equals("") ) {
			System.err.println("all consonants the same between words but order could be mixed REMOVING " + stopword);
		}
		*/
	
		//
		// starts with
		//
		if ( stopword.startsWith(mathword) && stopword.length() > 3 && mathword.length() > 2 && 
			(stopword.length() - mathword.length() > 4 ) ) {
			//System.err.println("stopword starts with mathword REMOVING " + stopword);
			return false;
		}
	
		if ( stopword_no_vowels.equals("") || mathword_no_vowels.equals("") )
		return true;

		//
		// one missing consonant in stopword
		//
		//System.err.println("stopword " + stopword + " mathword_no_vowels " + mathword_no_vowels);
		if ( ( stopword.length() > mathword_no_vowels.length() ) &&
			( stopword.length() <= mathword_no_vowels.length() * 2 ) &&
			( mathword_no_vowels.length() > 2 ) ) {
	
			Pattern pattern = Pattern.compile(mathword_no_vowels_wildcards);
			Matcher matcher = pattern.matcher(stopword_no_vowels);
			if ( matcher.matches() ) {
				//System.err.println(stopword_no_vowels + " matches " + mathword_no_vowels_wildcards);
				return false;
			}
			//else
				//System.err.println(mathword_no_vowels_wildcards + " does not math " + stopword_no_vowels);
	
		}
		//else
			//System.err.println("words not long enough for this comparison");
		//
		// consonants are in order but there is one extra consonant in at the beginning or ending of stopword
		// but only if there at least 3 consonants
		//
		/*
		if ( mathword_no_vowels.length() >= 3 && stopword_no_vowels.length() - mathword_no_vowels.length() == 1) {
			if ( stopword_no_vowels.replace(mathword_no_vowels, "").length() == 1 ) {
				System.err.println("one extra consonant in stopword " + stopword_no_vowels + " " + stopword + " mathword " + 
					mathword_no_vowels + " " + mathword + " REMOVING");
				return false;
			}
		}
		//
		// consonants are in order but there is one extra consonant in at the beginning or ending of mathword
		// but only if there at least 3 consonants
		//
		if ( stopword_no_vowels.length() >= 3 && mathword_no_vowels.length() - stopword_no_vowels.length() == 1) {
			if ( mathword_no_vowels.replace(stopword_no_vowels, "").length() == 1 ) {
				System.err.println("one extra consonant in mathword " + mathword_no_vowels +" " +  mathword + " stopword " + 
					stopword_no_vowels + " " + stopword + " REMOVING");
				return false;
			}
		}
		*/
	
		sounds_like_index++;
	}
	while ( sounds_like_index < sounds_like.length ) ;





	return true;
}



//
// search_string replacement_string new_string
//
public static String[][] replacement_strings = {
	{ "kt", "kt", "ct" },
	{ "mba", "mba$", "mber" },
	{ "ova", "^ova$", "over" },
	{ "fta", "fta$", "fter" }
};

public static String replace(String word) {
	if ( word == null )
		return word;

	int i;
	String [] replacement;
	String newString = word;

	for(i=0; i<replacement_strings.length; i++) {
		replacement = replacement_strings[i];
		if ( word.indexOf(replacement[0]) != -1 ) {
			newString = newString.replaceAll(replacement[1],
						    replacement[2]);
		}
	}

	return newString;
}

//
// handle the normal english -ies -es -s
//
// the mxit lingo -iez -ez -z
//
public static String singular(String word) {
	int pos;
	String newString = word;

	if ( word != null && word.length() > 4 && word.endsWith("ies") ) {
		pos = word.lastIndexOf("ies");
		newString  = word.substring(0, pos);
		newString = newString.concat("y");
	}
	else if ( word != null && word.length() > 4 && word.endsWith("iez") ) {
		pos = word.lastIndexOf("iez");
		newString  = word.substring(0, pos);
		newString = newString.concat("y");
	}
	else if ( word != null && word.length() > 3 && word.endsWith("es") ) {
		pos = word.lastIndexOf("s");
		newString = word.substring(0, pos);
	}
	else if ( word != null && word.length() > 3 && word.endsWith("ez") ) {
		pos = word.lastIndexOf("z");
		newString = word.substring(0, pos);
	}
	else if ( word != null && word.length() > 3 && word.endsWith("s") && ! word.endsWith("us") ) {
		pos = word.lastIndexOf("s");
		newString = word.substring(0, pos);
	}
	else if ( word != null && word.length() > 3 && word.endsWith("z") ) {
		pos = word.lastIndexOf("z");
		newString = word.substring(0, pos);
	}

	return newString;
}

public static String add_final_e(String word) {
	/*
	String vowels = "aeiou";
	String last_consonants = "bcdmnrstvz";
	String dipthongs_to_ignore = "oa ai ea ee";
	String newString = word;
	int last = word.length() - 1;

	if ( word.length() == 3 ) {
		char last_char = word.charAt(last);
		char second_last_char = word.charAt(last - 1);
		char first_char = word.charAt(last - 2);
		String dipthong = new String("" + first_char + second_last_char);
		if ( dipthongs_to_ignore.indexOf(dipthong) != -1  && 
		     last_consonants.indexOf(last_char) != -1 ) {
			// leave alone
		}
		else if ( last_consonants.indexOf(last_char) != -1  && 
				vowels.indexOf(second_last_char) != -1 &&
				!( last_char == 'r' && second_last_char == 'e') )
			newString = newString.concat("e");
		else if ( last_char == 'c' )
			newString = newString.concat("e");
		else if ( vowels.indexOf(last_char) != -1 )
			newString = newString.concat("e");
		return newString;
	}
	else if ( word.length() > 3 ) {

	
		char last_char = word.charAt(last);
		char second_last_char = word.charAt(last - 1);
		char third_last_char = word.charAt(last - 2);
		String dipthong = new String("" + third_last_char + second_last_char);
		if ( dipthongs_to_ignore.indexOf(dipthong) != -1  && 
		     last_consonants.indexOf(last_char) != -1 ) {
			// leave alone
		}
		else if ( last_consonants.indexOf(last_char) != -1  && 
				vowels.indexOf(second_last_char) != -1 &&
				!( last_char == 'r' && second_last_char == 'e') )
			newString = newString.concat("e");
		else if ( last_char == 'c' )
			newString = newString.concat("e");
		else if ( vowels.indexOf(last_char) != -1 )
			newString = newString.concat("e");
		
		return newString;
	}
	else
	*/
		return word;

}

public static String remove_all_vowels(String word) {
	String newString;

	newString = word.replaceAll("[aeiou]", "");

	return newString;
}

public static String remove_final_vowel(String word) {
	if ( word != null && word.length() > 3 ) {
		String newString = word;
		int pos = word.length() - 1;
		String letters_to_remove = "aeiouy";
		/*
		char last_char = word.charAt(pos);
		if ( letters_to_remove.indexOf(last_char) != -1 ) {
			newString = word.substring(0, pos);
			clean = false;
		}
		*/
		while ( letters_to_remove.indexOf( newString.charAt(pos) ) != -1 ) {
			newString = newString.substring(0, pos);
			if ( newString.length() == 0 ) {
				break;
			}
			pos = newString.length() - 1;
			clean = false;
		}
		return newString;
	}
	return word;
}

public static String remove_angular(String word) {
	if ( word == null )
		return word;
	int pos;
	String newString = word;

	if ( word.length() > 6 && word.endsWith("angular") ) {
		pos = word.lastIndexOf("angular");
		newString = word.substring(0, pos).concat("angle");
		clean = false;
	}

	return newString;
}

public static String remove_or(String word) {
	int pos;
	String newString = word;
	if ( word != null && word.length() > 4 && word.endsWith("or") && !word.endsWith("ior") ) {
		pos = word.lastIndexOf("or");
		newString = word.substring(0, pos);
		clean = false;
	}

	return newString;
}

public static String remove_al(String word) {
	int pos;
	String newString = word;
	
	if ( word != null && word.length() > 5 && word.endsWith("ial") ) {
		pos = word.lastIndexOf("ial");
		newString = word.substring(0, pos);
		clean = false;
	}
	else if ( word != null && word.length() > 5 && word.endsWith("al") ) {
		pos = word.lastIndexOf("al");
		newString = word.substring(0, pos);
		clean = false;
	}

	return newString;
}

public static String remove_er(String word) {
	if ( word == null )
		return null;
	int pos;
	String newString = word;
	
	if (word.length() > 4 && word.endsWith("ier") ) {
		pos = word.lastIndexOf("ier");
		newString = word.substring(0, pos);
		newString = newString.concat("y");
		clean = false;
	}
	else if (word.length() > 5 && word.endsWith("er") ) {
		pos = word.lastIndexOf("er");
		/*
		char last_char = word.charAt(pos - 1);
		String vowels = "aeiou";
		if ( vowels.indexOf(last_char) != -1 ) {
			newString = word.substring(0, pos + 1);
			clean = false;

			if ( newString.length() <= 2 )
				newString = word;
		}
		*/
		newString = word.substring(0, pos);
		clean = false;
	}
	//
	// if it ends with a special consonant and a r then it is a Mxit Lingo
	// past tense
	//
	else if ( word != null && word.length() > 4 && word.endsWith("r") ) {
		pos = word.lastIndexOf("r");
		char last_char = word.charAt(pos - 1);
		//
		// specificall did not include the consonants
		//
		//  l n r w
		String special_consonants = "bcdfghjkmpqstz";
		if ( special_consonants.indexOf(last_char) != -1 )  {
			newString = word.substring(0, pos);
			clean = false;
		}
		if ( newString.length() <= 2)
			newString = word;
	}

	return newString;
}

public static String remove_ed(String word) {
	int pos;
	String newString = word;
	
	if ( word != null && word.length() == 4 && word.endsWith("ied") ) {
		pos = word.lastIndexOf("ied");
		newString = word.substring(0, pos);
		newString = newString.concat("ie");
		clean = false;
	}
	else if ( word != null && word.length() > 4 && word.endsWith("ied") ) {
		pos = word.lastIndexOf("ied");
		newString = word.substring(0, pos);
		newString = newString.concat("y");
		clean = false;
	}
	else if ( word != null && word.length() > 3 && word.endsWith("ed") ) {
		pos = word.lastIndexOf("ed");
		char last_char = word.charAt(pos - 1);
		char second_last_char = word.charAt(pos - 2);
		String vowels = "aeiou";
		if ( vowels.indexOf(last_char) == -1 &&
			vowels.indexOf(second_last_char) != -1 ) {
			newString = add_final_e(word.substring(0, pos+1));
		}
		else {
			newString = add_final_e(word.substring(0, pos));
		}
		clean = false;

		if ( newString.length() <= 2 )
			newString = word;
	}
	//
	// if it ends with a special consonant and a d then it is a Mxit Lingo
	// past tense
	//
	else if ( word != null && word.length() > 3 && word.endsWith("d") ) {
		pos = word.lastIndexOf("d");
		char last_char = word.charAt(pos - 1);
		//
		// specificall did not include the consonants
		//
		//  l n r w
		String special_consonants = "bcdfghjkmpqstvz";
		if ( special_consonants.indexOf(last_char) != -1 ) {
			newString = word.substring(0, pos);
			clean = false;
		}
		if ( newString.length() <= 2)
			newString = word;
	}

	//System.err.println("remove_3d returning " + newString);
	return newString;
}

public static String [] special_est_words = {
	"honest",
	"interest",
	"invest",
	"suggest",
	"northwest",
	"southwest",
	"contest"
};

public static String remove_est(String word) {
	int pos;
	String newString = word;

	//System.err.println("word is " + word);
	
	if ( word != null && word.length() > 5 && word.endsWith("iest") ) {
		pos = word.lastIndexOf("iest");
		newString = word.substring(0, pos);
		newString = newString.concat("y");
		clean = false;
	}
	else if ( word != null && word.length() > 5 && word.endsWith("yest") ) {
		pos = word.lastIndexOf("yest");
		newString = word.substring(0, pos);
		newString = newString.concat("y");
		clean = false;
	}
	else if ( word != null && word.length() > 4 && word.endsWith("est") ) {
		pos = word.lastIndexOf("est");
		char last_char = word.charAt(pos - 1);
		//
		// look for words like guest
		//
		String vowels = "aeiou";
		if ( vowels.indexOf(last_char) != -1 )
			return word;
		int i;
		for(i=0; i<special_est_words.length; i++) {
			if  ( word.equals(special_est_words[i]) )
				return word;
		}
		newString = word.substring(0, pos);
		newString = add_final_e(newString);
		clean = false;
	}

	return newString;
}

public static String full_suffixes[] = {
	"full",
	"ful"
};

public static String remove_full(String word) {
	int pos;
	String newString = word;

	int i;
	for(i=0; i<full_suffixes.length; i++) {
		if ( word != null && word.length() > 5 && word.endsWith(full_suffixes[i]) ) {
			pos = word.lastIndexOf(full_suffixes[i]);
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
	}
	return newString;
}

public static String tric_suffixes[] = {
	"trical",
	"trically",
	"triclly",
	"tricly",
	"tric",
	"tical",
	"tically",
	"ticaly",
	"tic",
};

public static String remove_tric(String word) {
	int pos;
	String newString = word;

	int i;
	for(i=0; i<tric_suffixes.length; i++) {
		if ( word != null && word.length() > 5 && word.endsWith(tric_suffixes[i]) ) {
			pos = word.lastIndexOf(tric_suffixes[i]);
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
	}
	return newString;
}

public static String cally_suffixes[] = {
	"cally",
	"clly",
	"caly",
	"cly"
};

public static String remove_cally(String word) {
	int pos;
	String newString = word;

	int i;
	for(i=0; i<cally_suffixes.length; i++) {
		if ( word != null && word.length() > 5 && word.endsWith(cally_suffixes[i]) ) {
			pos = word.lastIndexOf(cally_suffixes[i]);
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
	}
	return newString;
}

public static String ent_ence_suffixes[] = {
	"ance",
	"anse",
	"ant",
	"ence",
	"ense",
	"ent"
};

public static String remove_ent_ence(String word) {
	int pos;
	String newString = word;

	int i;
	for(i=0; i<ent_ence_suffixes.length; i++) {
		if ( word != null && word.length() > 6 && word.endsWith(ent_ence_suffixes[i]) ) {
			pos = word.lastIndexOf(ent_ence_suffixes[i]);
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
	}
	return newString;
}

//
// there are lots of -ent words and we can't sort them out
// but most -ence and -ency will match an -ent word but not the other
// way round
//
public static String change_ence_to_ent(String word) {
	if ( word == null )
		return word;
	int pos;
	String newString = word;
	
	if (word.length() > 6 && 
		( word.endsWith("enc") || word.endsWith("ence") ||
			word.endsWith("ency") ) ) {
		pos = word.lastIndexOf("en");
		newString = word.substring(0, pos);
		newString = newString.concat("ent");
		clean = false;
	}

	return newString;
}




//
// special case for -ply and -bly
//
public static String remove_ly(String word) {
	int pos;
	String newString = word;
	
	if ( word != null && word.length() > 3 && word.endsWith("ly") ) {
		pos = word.lastIndexOf("ly");
		newString = word.substring(0, pos);
		clean = false;
		char ch = word.charAt(pos - 1);
		//
		// statistically this will be mutliply
		// keep the ly
		//
		if ( ch == 'p' ) {
			newString = newString.concat("le");
			//return word;
		}
		//
		// change to suffix ble
		//
		if ( ch == 'b' ) {
			newString = newString.concat("le");
		}
	}

	//System.err.println("remove_ly returning " + newString);
	return newString;
}

public static String ous_suffixes[] = {
	"eous",
	"ous",
	"os",
	"us"
};

public static String remove_ous(String word) {
	if ( word == null )
		return word;

	int pos;
	String newString = word;
	
	int i;
	
	for(i=0; i<ous_suffixes.length; i++) {
		if (word.length() > 5 && word.endsWith(ous_suffixes[i]) ) {
			pos = word.lastIndexOf(ous_suffixes[i]);
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
	}

	//System.err.println("remove_ly returning " + newString);
	return newString;
}
public static String tive_suffixes[] = {
	"icative",
	"itive",
	"tive",
	"tiv"
};

public static String remove_tive(String word) {
	if ( word == null )
		return word;

	int pos;
	String newString = word;
	
	int i;
	
	for(i=0; i<tive_suffixes.length; i++) {
		if (word.length() > 5 && word.endsWith(tive_suffixes[i]) ) {
			pos = word.lastIndexOf(tive_suffixes[i]);
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
	}

	//System.err.println("remove_ly returning " + newString);
	return newString;
}

public static String remove_doubles(String word) {
	if ( word == null )
		return null;
	String newString = word;
	char ch;
	for(ch = 'a'; ch <= 'z'; ch++) {
		String single_letter = new String("" + ch);
		String double_letters = new String("" + ch + ch);
		if ( word.indexOf(double_letters) != -1 ) {
			newString = word.replaceAll(double_letters, single_letter);
			clean = false;
			if ( newString.length() > 3 )
				return newString;
			else
				return word;
		}
	}

	return newString;
	
}

public static String[] sounds_shun = {
	"ication",
	"tion",
	"iton",  // common mispelling
	"ton",
	"tn",
	"sion",
	"ison", // common misspelling
	"son",
	"sin",
	"sn",
	"shun",
	"shon",
	"sun",
	"sunal",
	"sinal",
	"tional",
	"sional",
	"shunal",
	"sunal"
};

public static String remove_ion(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	for(i=0; i<sounds_shun.length; i++) {

		if ( word.length () > (sounds_shun[i].length() + 3) && word.endsWith(sounds_shun[i]) ) {
			pos = word.lastIndexOf(sounds_shun[i]);
			char ch = word.charAt(pos -1 );
			String vowels = "aeiou";
			if ( vowels.indexOf(ch) != -1 )
				pos--;
			newString = word.substring(0, pos);
			if ( ch == 'c' )
				newString = newString.concat("t");
			clean = false;
			break;
		}
	}


	return newString;
}

public static String remove_ing(String word) {
	if ( word == null )
		return null;
	int pos;
	String newString = word;

	String consonants = "bcdfgjklmnpqrstvwxyz";
	
	if ( word.length() > 4 && word.endsWith("ing") && ! word.endsWith("thing")) {
		pos = word.lastIndexOf("ing");

		newString = add_final_e(word.substring(0, pos) );
		clean = false;

		if ( newString.length() <= 2 )
			newString = word;
	}
	//
	// this only applies if there is a consonant
	// before it
	//
	else if ( word.length() > 5 && word.endsWith("in") && !word.endsWith("thin") ) {
		pos = word.lastIndexOf("in");
		char last_char = word.charAt(pos - 1);
		String vowels = "aeiou";
		if ( vowels.indexOf(last_char) == -1 ) {
			newString = word.substring(0, pos);
			clean = false;

			newString = add_final_e( word.substring(0, pos) );
			if ( newString.length() <= 2 )
				newString = word;
		}
	}
	//
	//
	//
	else if ( word.length() > 4 && word.endsWith("ng") && consonants.indexOf( word.charAt(word.length() - 1) ) != -1 ) {
		pos = word.lastIndexOf("ng");
		newString = word.substring(0, pos);
		clean = false;
	}

	

	//System.err.println("remove_ing returning " + newString);
	return newString;
}

//
// remove various -tant words
//
public static String [] tant_suffixes = {
	"tant",
	"tent",
	"tnt",
	"tint"
};

public static String remove_tant(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	for(i=0; i<tant_suffixes.length; i++ ) {

		if ( word.length () >  6 && word.endsWith(tant_suffixes[i]) ) {
			pos = word.lastIndexOf(tant_suffixes[i]);
			pos ++;
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
	}
	return newString;
			
}

public static String [] ment_suffixes = {
	"ment"
};

public static String remove_ment(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	for(i=0; i<ment_suffixes.length; i++ ) {

		if ( word.length () >  6 && word.endsWith(ment_suffixes[i]) ) {
			pos = word.lastIndexOf(ment_suffixes[i]);
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
	}
	return newString;
			
}

public static String ian_suffixes [] = {
	"ian",
	"ean"
};

public static String remove_ian(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	for(i=0; i<ian_suffixes.length; i++ ) {

		if ( clean && word.length () >  6 && word.endsWith(ian_suffixes[i]) ) {
			pos = word.lastIndexOf(ian_suffixes[i]);
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
		else if ( !clean && word.length() > 6 && word.endsWith(ian_suffixes[i].substring(0, ian_suffixes[i].length() -1) ) ) {
			pos = word.lastIndexOf(ian_suffixes[i].substring(0, ian_suffixes[i].length() - 1) );
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
	}
	return newString;
}

public static String ic_suffixes [] = {
	"ic"
};

public static String remove_ic(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	//System.err.print("word is " + word);
	for(i=0; i<ic_suffixes.length; i++ ) {

		if (word.length () >  6 && word.endsWith(ic_suffixes[i]) ) {
			pos = word.lastIndexOf(ic_suffixes[i]);
			newString = word.substring(0, pos);
			clean = false;
			break;
		}
	}
	//System.err.println(" newString is " + newString);
	return newString;
}
public static String ize_suffixes [] = {
	"ize",
	"ise"
};

public static String remove_ize(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	//System.out.println("word is " + word + " clean is " + clean);
	for(i=0; i<ize_suffixes.length; i++ ) {

		if ( word.length () >  4 && word.endsWith(ize_suffixes[i]) ) {
			pos = word.lastIndexOf(ize_suffixes[i]);
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
		else if ( !clean && word.length() > 4 && word.endsWith(ize_suffixes[i].substring(0, ize_suffixes[i].length() -1) ) ) {
			pos = word.lastIndexOf(ize_suffixes[i].substring(0, ize_suffixes[i].length() - 1) );
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
	}
	//System.out.println("newString is " + newString);
	return newString;
}

public static String al_suffixes [] = {
	"cal"
};

public static String remove_cal(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	for(i=0; i<al_suffixes.length; i++ ) {

		if ( clean && word.length () >  4 && word.endsWith(al_suffixes[i]) ) {
			pos = word.lastIndexOf(al_suffixes[i]);
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
		else if ( !clean && word.length() > 4 && word.endsWith(al_suffixes[i].substring(0, al_suffixes[i].length() -1) ) ) {
			pos = word.lastIndexOf(al_suffixes[i].substring(0, al_suffixes[i].length() - 1) );
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
	}
	return newString;
}

public static String ate_suffixes [] = {
	"ate"
};

public static String remove_ate(String word) {
	if ( word == null )
		return null;

	int pos;
	String newString = word;

	int i;
	for(i=0; i<ate_suffixes.length; i++ ) {

		if ( clean && word.length () >  4 && word.endsWith(ate_suffixes[i]) ) {
			pos = word.lastIndexOf(ate_suffixes[i]);
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
		else if ( !clean && word.length() > 4 && word.endsWith(ate_suffixes[i].substring(0, ate_suffixes[i].length() -1) ) ) {
			pos = word.lastIndexOf(ate_suffixes[i].substring(0, ate_suffixes[i].length() - 1) );
			newString = word.substring(0, pos+1);
			clean = false;
			break;
		}
	}
	return newString;
}

public static String remove_ble(String word) {
	if ( word == null )
		return null;
	int pos;
	String newString = word;
	
	if ( word.length() > 4 && word.endsWith("ble") ) {
		pos = word.lastIndexOf("ble");
		//
		// check for ible able eble
		//
		if ( word.charAt(pos-1) == 'a' ||
		     word.charAt(pos-1) == 'e' ||
		     word.charAt(pos-1) == 'i' ) {
			newString = word.substring(0, pos-1);
			clean = false;
		}
		else {
			newString = word.substring(0, pos);
			clean = false;
		}

		if ( newString.length() <= 4 )
			newString = word;
	}

	//System.err.println("remove_ble returning " + newString);
	return newString;
}

public static String stem(String word) {
	if ( word == null )
		return null;
	
	clean = true;

	//System.out.println("0- " + word + " " + word.length());
	String tmp = replace(word.trim());
	//System.out.println("1- " + tmp + " " + tmp.length());

	tmp = singular(tmp);
	//System.out.println("2- " + tmp + " " + tmp.length());

	tmp = remove_ent_ence(tmp);
	//tmp = change_ence_to_ent(tmp);
	//System.out.println("3- " + tmp + " " + tmp.length());

	tmp = remove_al(tmp);
	//System.out.println("4- " + tmp);

	tmp = remove_ian(tmp);
	//System.out.println("5- " + tmp);

	tmp = remove_angular(tmp);
	//System.out.println("6- " + tmp);

	tmp = remove_full(tmp);
	//System.out.println("7- " + tmp);

	tmp = remove_tant(tmp);
	//System.out.println("8- " + tmp);

	tmp = remove_ment(tmp);
	//System.out.println("9- " + tmp);

	tmp = remove_est(tmp);
	//System.out.println("10- " + tmp);

	tmp = remove_est(tmp);
	//System.out.println("11- " + tmp);

	tmp = remove_tric(tmp);
	//System.out.println("11a- " + tmp);

	tmp = remove_cally(tmp);
	//System.out.println("12- " + tmp);

	tmp = remove_ly(tmp);
	//System.out.println("13- " + tmp);

	tmp = remove_final_vowel(tmp);
	//System.out.println("1a " + tmp + " " + tmp.length());


	tmp = remove_ous(tmp);
	//System.out.println("13a- " + tmp);

	tmp = remove_cal(tmp);
	//System.out.println("14- " + tmp);

	tmp = remove_tive(tmp);
	//System.out.println("15- " + tmp);

	tmp = remove_ing(tmp);
	//System.out.println("16- " + tmp);

	tmp = remove_ion(tmp);
	//System.out.println("17- " + tmp);

	tmp = singular(tmp);
	//System.out.println("18- " + tmp);

	tmp = remove_ed(tmp);
	//System.out.println("19- " + tmp);

	tmp = remove_ate(tmp);
	//System.out.println("20- " + tmp);

	tmp = remove_ble(tmp);
	//System.out.println("21- " + tmp);

	tmp = remove_ize(tmp);
	//System.out.println("22- " + tmp);

	tmp = remove_final_vowel(tmp);
	//System.out.println("23- " + tmp);

	tmp = remove_er(tmp);
	//System.out.println("24- " + tmp);

	tmp = remove_or(tmp);
	//System.out.println("25- " + tmp);

	tmp = remove_ate(tmp);
	//System.out.println("26- " + tmp);

	tmp = remove_ic(tmp);
	//System.out.println("27- " + tmp);

	tmp = remove_final_vowel(tmp);
	//System.out.println("28- " + tmp);

	tmp = remove_doubles(tmp);
	//System.out.println("29- " + tmp);

	//tmp = remove_all_vowels(tmp);
	//System.out.println("30- " + tmp);

	//String tmp = remove_doubles(remove_final_vowel(remove_ble(remove_ed(remove_ing(remove_ion(remove_ly(remove_er(remove_est(remove_ment(remove_tant(singular(word))))))))))));

	return tmp;
}

public static boolean compareWordAndStem(String word) {
	//String stm = stem(word);
	String stm = remove_all_vowels(stem(word));
	return !stm.equals(word);
}

/*
  stdin stdou
  print word and stem
*/
public static void main(String [] args) {
	try {
		BufferedReader bufferedReader = new BufferedReader(
				new InputStreamReader(System.in));

		String line = new String();
		String tmp;
	
		while ( (line = bufferedReader.readLine()) != null ) {
			tmp = stem(line);
			System.out.println(tmp);
		}
	}
	catch ( Throwable t ) {
		System.out.println("throwing " + t);
	}
	
}

}
